/**
 * 版权所有(C)，上海勾芒信息科技，2017，所有权利保留。
 * 
 * 项目名：	cards-web
 * 文件名：	WxComponentServiceDelegateImpl.java
 * 模块说明：	
 * 修改历史：
 * 2017年5月25日 - Debenson - 创建。
 */
package me.chanjar.weixin.component.api.app.impl;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHost;
import org.apache.http.impl.client.CloseableHttpClient;

import com.alex.wechat.app.config.WxAppContext;

import cn.binarywang.wx.miniapp.api.WxMaMsgService;
import me.chanjar.weixin.common.WxNetworkingSupport;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.URL;
import me.chanjar.weixin.component.api.WxCompConfigStorage;
import me.chanjar.weixin.component.api.WxCompService;
import me.chanjar.weixin.component.api.app.WxCompMaCodeService;
import me.chanjar.weixin.component.api.app.WxCompMaDomainService;
import me.chanjar.weixin.component.api.app.WxCompMaMessageTemplateService;
import me.chanjar.weixin.component.api.app.WxCompMaServiceDelegate;
import me.chanjar.weixin.component.api.app.WxCompMaTesterService;

/**
 * 小程序服务代理
 * 
 * @author Debenson
 * @since 0.1
 */
public class WxCompMaServiceDelegateImpl extends WxNetworkingSupport
    implements WxCompMaServiceDelegate {
  private static final String ACCESS_TOKEN = "access_token";

  private final WxCompMaDomainService compAppDomainService;
  private final WxCompMaCodeService compAppCodeService;
  private final WxCompService wxComponentService;
  private final WxCompMaTesterService compAppTesterService;
  private final WxMaMsgService compMaMessageService;
  private final WxCompMaMessageTemplateService compMaMessageTemplateService;

  public WxCompMaServiceDelegateImpl(WxCompService wxComponentService) {
    this.wxComponentService = wxComponentService;
    this.compAppDomainService = new WxCompMaDomainServiceImpl(this);
    this.compAppCodeService = new WxCompMaCodeServiceImpl(this);
    this.compAppTesterService = new WxCompMaTesterServiceImpl(this);
    this.compMaMessageService = new WxCompMaMessageServiceImpl(this);
    this.compMaMessageTemplateService = new WxCompMaMessageTemplateServiceImpl(this);
  }

  @Override
  public String appendAccessToken(String url) throws WxErrorException {
    URL urlMapper = new URL(url);
    if (urlMapper.getParameter(ACCESS_TOKEN, null) != null) {
      throw new IllegalArgumentException("uri参数中不允许有" + ACCESS_TOKEN + ": " + url);
    }

    final String appId = getCurrentAppId();
    final String token = wxComponentService.getAuthorizerAccessToken(appId);
    urlMapper.addParameter(ACCESS_TOKEN, token);
    return urlMapper.toString();
  }

  @Override
  public boolean expireIfInvalidToken(int code) {
    boolean result = code == 42001 || code == 40001 || code == 40014;
    if (result) {
      final String appId = getCurrentAppId();
      getComponentConfig().expireAuthorizerAccessToken(appId);
    }
    return result;
  }

  /**
   * 取得当前公众号或小程序的AppId
   * 
   * @return
   */
  protected String getCurrentAppId() {
    String appId = WxAppContext.getAppId();
    if (StringUtils.isBlank(appId)) {
      throw new RuntimeException("没有设置当前公众号或小程序的AppId");
    }
    return appId;
  }

  @Override
  public WxCompConfigStorage getComponentConfig() {
    return this.wxComponentService.getConfigStorage();
  }

  @Override
  public WxCompService getComponentService() {
    return wxComponentService;
  }

  @Override
  public WxCompMaDomainService getMaDomainService() {
    return this.compAppDomainService;
  }

  @Override
  public WxCompMaCodeService getMaCodeService() {
    return this.compAppCodeService;
  }

  @Override
  public WxCompMaTesterService getMaTesterService() {
    return this.compAppTesterService;
  }

  @Override
  public WxMaMsgService getMaMessageService() {
    return this.compMaMessageService;
  }

  @Override
  public WxCompMaMessageTemplateService getMaMessageTemplateService() {
    return this.compMaMessageTemplateService;
  }

  @Override
  public CloseableHttpClient getRequestHttpClient() {
    return getComponentService().getRequestHttpClient();
  }

  @Override
  public HttpHost getRequestHttpProxy() {
    return getComponentService().getRequestHttpProxy();
  }

}
